package com.yxhl.zoume.core.busticket.presenter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.yxhl.protobuf.BizOrderRequest;
import com.yxhl.protobuf.BizOrderResponse;
import com.yxhl.protobuf.ClientType;
import com.yxhl.protobuf.CommonReqParams;
import com.yxhl.protobuf.Contract;
import com.yxhl.protobuf.ContractType;
import com.yxhl.protobuf.GenderType;
import com.yxhl.protobuf.IdType;
import com.yxhl.protobuf.OneBusEntry;
import com.yxhl.protobuf.OneYxBusInfoRequest;
import com.yxhl.protobuf.OneYxBusInfoResponse;
import com.yxhl.protobuf.PubLockTicketRequest;
import com.yxhl.protobuf.PubLockTicketResponse;
import com.yxhl.protobuf.PubTicketEntry;
import com.yxhl.zoume.common.presenter.BasePresenter;
import com.yxhl.zoume.common.presenter.IPresenter;
import com.yxhl.zoume.common.ui.view.BaseView;
import com.yxhl.zoume.core.busticket.ui.info.ZMContractType;
import com.yxhl.zoume.core.busticket.ui.info.ZMGenderType;
import com.yxhl.zoume.core.busticket.view.BusTicketOrderView;
import com.yxhl.zoume.data.http.model.busticket.ZMBusTicketOrder;
import com.yxhl.zoume.data.http.model.coupon.CouponInfo;
import com.yxhl.zoume.data.http.model.passenger.ZMPassenger;
import com.yxhl.zoume.domain.interactor.ZMSubscriber;
import com.yxhl.zoume.domain.interactor.busticket.GenerateSetTimeBusOrderUseCase;
import com.yxhl.zoume.domain.interactor.busticket.GetBusTicketDetailUseCase;
import com.yxhl.zoume.domain.interactor.busticket.LockTicketsUseCase;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

/**
 * Created by Xboy on 16/4/21.
 */
public class BusTicketOrderPresenter extends BasePresenter implements IPresenter {

    private BusTicketOrderView busTicketOrderView;

    private GetBusTicketDetailUseCase getBusTicketDetailUseCase;

    private LockTicketsUseCase lockTicketsUseCase;

    private GenerateSetTimeBusOrderUseCase generateSetTimeBusOrderUseCase;

    @Inject
    public BusTicketOrderPresenter(Context context,
                                   GetBusTicketDetailUseCase getBusTicketDetailUseCase,
                                   LockTicketsUseCase lockTicketsUseCase,
                                   GenerateSetTimeBusOrderUseCase generateSetTimeBusOrderUseCase) {
        super(context);
        this.getBusTicketDetailUseCase = getBusTicketDetailUseCase;
        this.lockTicketsUseCase = lockTicketsUseCase;
        this.generateSetTimeBusOrderUseCase = generateSetTimeBusOrderUseCase;
    }

    @Override
    public void attachView(BaseView view) {
        this.busTicketOrderView = (BusTicketOrderView) view;
    }

    /**
     * 获取当前车次详情
     *
     * @param param
     */
    public void getBusServiceDetail(OneYxBusInfoRequest param) {
        busTicketOrderView.waitingForBusServiceDetailRequest(true);

        getBusTicketDetailUseCase.execute(param,new ZMSubscriber<OneYxBusInfoResponse>() {
            @Override
            public void onCompleted() {
                super.onCompleted();
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                busTicketOrderView.waitingForBusServiceDetailRequest(false);
                busTicketOrderView.showErrorMessage(e.getLocalizedMessage());
            }

            @Override
            public void onNext(OneYxBusInfoResponse getBusServiceDetailResponse) {
                super.onNext(getBusServiceDetailResponse);
                busTicketOrderView.waitingForBusServiceDetailRequest(false);

                if (getBusServiceDetailResponse.getIsSucc().equals("true")) {
                    OneBusEntry queryResult = getBusServiceDetailResponse.getOneBusInfo();
                    busTicketOrderView.renderBusServiceDetail(queryResult);
                } else {
                    // 错误处理
                    String resultMsg = getBusServiceDetailResponse.getResultMsg();
                    busTicketOrderView.renderOnFailure(resultMsg);
                }
            }
        });
    }

    /**
     * 巴士车票：锁票
     *
     * @param busService    订单信息
     * @param passengerList 乘车人信息
     * @param ticketTaker   取票人信息
     * @param perfectCoupon
     */
    public void lockTickets(final OneBusEntry busService, List<ZMPassenger> passengerList, ZMPassenger ticketTaker, CouponInfo perfectCoupon) {
        busTicketOrderView.waitingForOrderConfirm(true);
        long userCouponId = 0;
        double discountFee = 0.0D;
        if (null != perfectCoupon) {
            userCouponId = perfectCoupon.getUserCouponId();
            discountFee = perfectCoupon.getDiscountFee();
        }
        //构造乘车人信息集合
        List<Contract> contractList = getPassengerList(passengerList);

        PubLockTicketRequest lockTicketRequest = PubLockTicketRequest.newBuilder()
                .setBaseRequest(getCommonReqParams())
                .setStartStationCode(busService.getStartStationCode())
                .setEndStationCode(busService.getEndStationCode())
                .setEnd(busService.getEndStationCode())
                .setStartStationName(busService.getStartStationName())
                .setEndStationName(busService.getEndStationName())
                .setGmtDepartDate(busService.getGmtDepartDate())
                .setGmtDepartTime(busService.getGmtDepartTime())
                .setScheduleNo(busService.getScheduleNo())
                .setOrderSerial("")
                .setAmount(String.valueOf(contractList.size()))
                .setTicketPrice(busService.getTicketPrice())
                .setSysNo(busService.getSysNo())
                .setGetTicketMobile(ticketTaker.getMobileNumber())
                .setName(ticketTaker.getRealName())
                .setIdNumber(ticketTaker.getIdNumber())
                .addAllContracts(contractList)
                .setType(busService.getType())
                .setCouponUserRelId(userCouponId)
                .setDiscountFee(discountFee)
                .build();

        lockTicketsUseCase.execute(lockTicketRequest,new ZMSubscriber<PubLockTicketResponse>() {
            @Override
            public void onCompleted() {
                super.onCompleted();
            }

            @Override
            public void onError(Throwable e) {
                super.onError(e);
                busTicketOrderView.waitingForOrderConfirm(false);
                busTicketOrderView.showErrorMessage(e.getLocalizedMessage());
            }

            @Override
            public void onNext(PubLockTicketResponse pubLockTicketResponse) {
                super.onNext(pubLockTicketResponse);
                busTicketOrderView.waitingForOrderConfirm(false);

                String isSucc = pubLockTicketResponse.getIsSucc().trim();
                if ("true".equalsIgnoreCase(isSucc)) {

                    PubTicketEntry pubTicketEntry = pubLockTicketResponse.getPubTicketEntry();
                    ZMBusTicketOrder busTicketOrder = getZmBusTicketOrder(pubTicketEntry);

                    busTicketOrderView.renderBusTicketOrder(busTicketOrder);
                } else {
                    String resultMsg = pubLockTicketResponse.getResultMsg();
                    busTicketOrderView.renderOnFailure(resultMsg);
                }
            }
        });
    }

    @NonNull
    private ZMBusTicketOrder getZmBusTicketOrder(PubTicketEntry pubTicketEntry) {

        String passengerCountStr = pubTicketEntry.getAmount();
        int passengerCount;
        if (!TextUtils.isEmpty(passengerCountStr)) {
            passengerCount = Integer.parseInt(passengerCountStr);
        } else {
            passengerCount = 0;
        }
        String orderSerial = pubTicketEntry.getOrderSerial();
        String totalFee = pubTicketEntry.getTotalFee();

        ZMBusTicketOrder busTicketOrder = new ZMBusTicketOrder(orderSerial, passengerCount, totalFee);

        String startStationName = pubTicketEntry.getStartStationName();
        String arrivalStationName = pubTicketEntry.getEndStationName();
        String gmtDepartData = pubTicketEntry.getGmtDepartDate();
        String gmtDepartTime = pubTicketEntry.getGmtDepartTime();

        busTicketOrder.setStartCityName(startStationName);
        busTicketOrder.setArrivalStationName(arrivalStationName);
        busTicketOrder.setTicketPrice(totalFee);
        busTicketOrder.setDepartDate(gmtDepartData);
        busTicketOrder.setDepartTime(gmtDepartTime);

        return busTicketOrder;
    }

    /**
     * 确认订单
     *
     * @param requestBuilder
     */
    public void generateOrder(final BizOrderRequest.Builder requestBuilder) {
        busTicketOrderView.waitingForOrderConfirm(true);

        CommonReqParams.Builder commReqBuilder = CommonReqParams.newBuilder();
        commReqBuilder.setClientSystem(CLIENT_SYSTEM)
                .setClientType(ClientType.USER)
                .setClientVersion(getClientVersionName())
                .setToken(getToken());
        requestBuilder.setCommonReqParams(commReqBuilder);

        // mobile
        requestBuilder.setMobile(getMobile());

        generateSetTimeBusOrderUseCase.execute(requestBuilder.build(),new ZMSubscriber<BizOrderResponse>() {
            @Override
            public void onError(Throwable e) {
                super.onError(e);
                busTicketOrderView.waitingForOrderConfirm(false);
            }

            @Override
            public void onNext(BizOrderResponse response) {
                super.onNext(response);
                busTicketOrderView.waitingForOrderConfirm(false);
                if (response.getCommonRespParams().getIsSucc().equals("true")) {
                    busTicketOrderView.renderFixedTimeBusOrder(response.getOrderFieldses(0));
                } else {
                    String resultMsg = response.getCommonRespParams().getResultMsg();
                    busTicketOrderView.renderOnFailure(resultMsg);
                }
            }
        });
    }


    /**
     * 获取乘车人信息集合
     *
     * @param passengerList
     * @return
     */
    @NonNull
    private List<Contract> getPassengerList(List<ZMPassenger> passengerList) {
        List<Contract> contractList = new ArrayList<>();
        for (ZMPassenger passenger : passengerList) {
            Contract contract = Contract.newBuilder()
                    .setMobile(passenger.getMobileNumber())
                    .setIdNumber(passenger.getIdNumber())
                    .setContractType(getContractType(passenger.getPsgerCategory()))
                    .setId(Long.parseLong(passenger.getPassengerId()))
                    .setIdType(IdType.IDCARD)
                    .setGender(getGenderType(passenger.getGender()))
                    .setRealname(passenger.getRealName())
                    .build();
            contractList.add(contract);
        }
        return contractList;
    }

//    private CommonReqParams getCommonReqParams() {
//        return CommonReqParams.newBuilder()
//                .setClientSystem("Android")
//                .setClientType(ClientType.USER)
//                .setClientVersion(getClientVersionName())
//                .setToken(getToken())
//                .setMobile(getMobile())
//                .build();
//    }

    /**
     * 获取乘车人类型(成人/儿童)
     *
     * @param passengerType
     * @return
     */
    @Nullable
    private ContractType getContractType(int passengerType) {
        ContractType contractType;
        switch (passengerType) {
            case ZMContractType.ADULT:
                contractType = ContractType.ADULT;
                break;
            case ZMContractType.CHILD:
                contractType = ContractType.CHILDREN;
                break;
            default:
                contractType = ContractType.ADULT;
        }
        return contractType;
    }

    /**
     * 获取乘车人性别类型
     *
     * @param type
     * @return
     */
    private GenderType getGenderType(int type) {
        GenderType ret;
        switch (type) {
            case ZMGenderType.MAILE:
                ret = GenderType.MALE;
                break;
            case ZMGenderType.FEMAIL:
                ret = GenderType.FEMALE;
                break;
            default:
                ret = GenderType.MALE;
        }
        return ret;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lockTicketsUseCase.unsubscribe();
    }
}
